<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>宁波城市宣传</title>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <style>
        :root{
            --primary:#004c70;        /* 宁波港蓝 */
            --accent:#d4a574;         /* 天一阁米金 */
            --secondary:#2a9d8f;      /* 新增：海港绿 */
            --light:#f8f9fa;          /* 新增：浅色背景 */
            --dark:#1a1a2e;           /* 新增：深色文字 */
            --radius:20px;
            --maxWidth:720px;
            --shadow:0 10px 30px rgba(0,0,0,0.1);
            --hover-shadow:0 15px 40px rgba(0,0,0,0.15);
            font-family: 'Noto Sans SC', 'PingFang SC', 'Microsoft YaHei', sans-serif;
        }
        *{box-sizing:border-box;margin:0;padding:0}

        /* 添加带有花纹的页面背景 */
        body{
            background-color: #f0f5ff;
            background-image:
                    radial-gradient(circle at 15% 50%, rgba(0, 76, 112, 0.08) 0%, transparent 20%),
                    radial-gradient(circle at 85% 30%, rgba(42, 157, 143, 0.08) 0%, transparent 20%),
                    radial-gradient(circle at 50% 80%, rgba(212, 165, 116, 0.08) 0%, transparent 20%),
                    linear-gradient(45deg, transparent 49%, rgba(0, 76, 112, 0.03) 49%, rgba(0, 76, 112, 0.03) 51%, transparent 51%),
                    linear-gradient(-45deg, transparent 49%, rgba(42, 157, 143, 0.03) 49%, rgba(42, 157, 143, 0.03) 51%, transparent 51%);
            background-size:
                    100% 100%,
                    100% 100%,
                    100% 100%,
                    30px 30px,
                    30px 30px;
            background-position:
                    0 0,
                    0 0,
                    0 0,
                    0 0,
                    0 0;
            color:var(--dark);
            line-height:1.7;
            -webkit-text-size-adjust:100%;
            overflow-x:hidden;
            position: relative;
            min-height: 100vh;
        }

        /* 添加顶部装饰性花纹 */
        .top-pattern {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 150px;
            background:
                    linear-gradient(135deg, var(--primary) 0%, transparent 70%),
                    repeating-linear-gradient(45deg, transparent, transparent 10px, rgba(255,255,255,0.1) 10px, rgba(255,255,255,0.1) 20px);
            opacity: 0.15;
            z-index: -1;
        }

        /* 添加底部装饰性花纹 */
        .bottom-pattern {
            position: absolute;
            bottom: 0;
            left: 0;
            width: 100%;
            height: 150px;
            background:
                    linear-gradient(-45deg, var(--secondary) 0%, transparent 70%),
                    repeating-linear-gradient(-45deg, transparent, transparent 10px, rgba(255,255,255,0.1) 10px, rgba(255,255,255,0.1) 20px);
            opacity: 0.15;
            z-index: -1;
        }

        /* 添加动态背景元素 */
        .bg-elements {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            z-index: -1;
            overflow: hidden;
        }

        .bg-element {
            position: absolute;
            opacity: 0.1;
            animation: float 20s infinite linear;
        }

        .bg-element:nth-child(1) {
            top: 10%;
            left: 5%;
            width: 120px;
            height: 120px;
            background:
                    radial-gradient(circle, var(--primary) 0%, transparent 70%),
                    repeating-linear-gradient(45deg, transparent, transparent 5px, var(--accent) 5px, var(--accent) 10px);
            border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%;
            animation-delay: 0s;
        }

        .bg-element:nth-child(2) {
            top: 70%;
            left: 80%;
            width: 100px;
            height: 100px;
            background:
                    radial-gradient(circle, var(--secondary) 0%, transparent 70%),
                    repeating-linear-gradient(-45deg, transparent, transparent 5px, var(--primary) 5px, var(--primary) 10px);
            border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%;
            animation-delay: -5s;
            animation-duration: 25s;
        }

        .bg-element:nth-child(3) {
            top: 40%;
            left: 90%;
            width: 80px;
            height: 80px;
            background:
                    radial-gradient(circle, var(--accent) 0%, transparent 70%),
                    repeating-linear-gradient(0deg, transparent, transparent 5px, var(--secondary) 5px, var(--secondary) 10px);
            border-radius: 40% 60% 70% 30% / 40% 50% 60% 60%;
            animation-delay: -10s;
            animation-duration: 30s;
        }

        @keyframes float {
            0% {
                transform: translateY(0) rotate(0deg);
            }
            25% {
                transform: translateY(-20px) rotate(90deg);
            }
            50% {
                transform: translateY(0) rotate(180deg);
            }
            75% {
                transform: translateY(20px) rotate(270deg);
            }
            100% {
                transform: translateY(0) rotate(360deg);
            }
        }

        /* ===== 平滑滚动 ===== */
        html {
            scroll-behavior: smooth;
        }

        /* ===== 加载动画 ===== */
        @keyframes fadeIn {
            from { opacity: 0; }
            to { opacity: 1; }
        }

        /* ===== Hero（全宽航拍 + 底部渐变） ===== */
        .hero{
            height:100vh;
            display:flex;
            flex-direction:column;
            align-items:center;
            justify-content:center;
            text-align:center;
            color:#fff;
            padding:24px;
            position:relative;
            background-image:linear-gradient(135deg, rgba(0,76,112,0.85) 0%, rgba(42,157,143,0.8) 100%), var(--bg);
            background-size:cover;
            background-position:center;
            background-attachment: fixed; /* 视差效果 */
        }
        .hero::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: radial-gradient(ellipse at center, transparent 0%, rgba(0,0,0,0.3) 100%);
            z-index: 1;
        }
        .hero-content {
            position: relative;
            z-index: 2;
            max-width: 800px;
            animation: fadeIn 1.5s ease-out;
        }
        .hero h1{
            font-family: 'Noto Serif SC', serif;
            font-size:clamp(2.5rem, 10vw, 4.5rem);
            letter-spacing:2px;
            margin-bottom:20px;
            text-shadow:0 2px 10px rgba(0,0,0,0.3);
            font-weight:700;
            line-height:1.2;
        }
        .hero p{
            font-size:clamp(1.1rem, 4vw, 1.5rem);
            opacity:0.95;
            margin-bottom:40px;
            text-shadow:0 1px 5px rgba(0,0,0,0.3);
            max-width:600px;
            margin-left:auto;
            margin-right:auto;
            font-weight:300;
        }
        .play-button{
            background:linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%);
            color:#fff;
            border:none;
            padding:16px 40px;
            border-radius:50px;
            font-size:18px;
            cursor:pointer;
            transition:all .4s ease;
            box-shadow:0 6px 20px rgba(0,76,112,0.4);
            font-weight:600;
            letter-spacing:1px;
            position:relative;
            overflow:hidden;
        }
        .play-button::after {
            content: '';
            position: absolute;
            top: 0;
            left: -100%;
            width: 100%;
            height: 100%;
            background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent);
            transition: left 0.5s;
        }
        .play-button:hover::after {
            left: 100%;
        }
        .play-button:hover{
            transform:translateY(-5px);
            box-shadow:0 12px 25px rgba(0,76,112,0.5);
        }
        .audio-tip{
            margin-top:15px;
            font-size:14px;
            opacity:0.9;
        }
        .scroll-tip{
            position:absolute;
            bottom:30px;
            font-size:28px;
            animation:bounce 2s infinite;
            color:rgba(255,255,255,0.8);
            z-index:2;
        }
        #audio-element{display:none}

        /* ===== 竖版卡片 ===== */
        .container{
            max-width:var(--maxWidth);
            margin:0 auto;
            padding:20px;
        }
        .card{
            background:#fff;
            border-radius:var(--radius);
            overflow:hidden;
            margin-bottom:30px;
            box-shadow:var(--shadow);
            animation:fadeInUp .8s both;
            transition:transform 0.3s ease, box-shadow 0.3s ease;
            position:relative;
            border: 1px solid rgba(0, 76, 112, 0.1);
        }
        .card:hover{
            transform:translateY(-10px);
            box-shadow:var(--hover-shadow);
        }
        .card::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            height: 4px;
            background: linear-gradient(90deg, var(--primary), var(--accent));
            z-index: 1;
        }
        .card img,.card video{
            width:100%;
            display:block;
            aspect-ratio:4/5;
            object-fit:cover;
            transition:transform 0.5s ease;
        }
        .card:hover img, .card:hover video {
            transform: scale(1.05);
        }
        .card video{background:#000}
        .txt{
            padding:25px 30px 30px;
            position:relative;
        }
        .txt h3{
            font-size:1.5rem;
            margin-bottom:12px;
            color:var(--primary);
            font-weight:600;
            font-family: 'Noto Serif SC', serif;
        }
        .txt p{
            color:#555;
            font-size:1.05rem;
            line-height:1.8;
        }

        /* ===== 滑动图/视频 ===== */
        .swipe{
            display:flex;
            overflow-x:auto;
            scroll-snap-type:x mandatory;
            -webkit-overflow-scrolling:touch;
            scrollbar-width:none;
            -ms-overflow-style:none;
        }
        .swipe::-webkit-scrollbar{display:none}
        .swipe img,.swipe video{
            flex:0 0 100%;
            scroll-snap-align:start;
        }
        .swipe-indicator{
            display:flex;
            justify-content:center;
            padding:15px 0 20px;
        }
        .swipe-dot{
            width:10px;
            height:10px;
            border-radius:50%;
            background:#ccc;
            margin:0 6px;
            transition:background .3s, transform .3s;
        }
        .swipe-dot.active{
            background:var(--primary);
            transform: scale(1.2);
        }

        /* ===== 图文项样式 ===== */
        .mixed-item {
            background: #fff;
            border-radius: var(--radius);
            overflow: hidden;
            margin-bottom: 0;
            box-shadow: 0 4px 15px rgba(0,0,0,0.08);
            transition: transform 0.3s ease;
            border: 1px solid rgba(0, 76, 112, 0.1);
        }
        .mixed-item:hover {
            transform: translateY(-5px);
        }
        .mixed-item-margin {
            margin-top: 25px;
        }
        .mixed-item img {
            width: 100%;
            display: block;
            aspect-ratio: 4/5;
            object-fit: cover;
            transition: transform 0.5s ease;
        }
        .mixed-item:hover img {
            transform: scale(1.03);
        }
        .mixed-item .txt {
            padding: 25px 30px 30px;
        }
        .mixed-item .txt p {
            color: #555;
            line-height: 1.8;
            margin: 0;
            font-size: 1.05rem;
        }

        /* ===== 页脚 ===== */
        .footer {
            background: linear-gradient(135deg, var(--primary) 0%, var(--dark) 100%);
            color: white;
            text-align: center;
            padding: 40px 20px;
            margin-top: 50px;
            position: relative;
        }

        /* 为页脚添加装饰 */
        .footer::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 5px;
            background: linear-gradient(90deg, var(--accent), var(--secondary), var(--accent));
        }

        .footer p {
            margin: 10px 0;
            opacity: 0.8;
        }
        .footer-links {
            display: flex;
            justify-content: center;
            gap: 20px;
            margin-top: 20px;
        }
        .footer-link {
            color: rgba(255,255,255,0.7);
            text-decoration: none;
            transition: color 0.3s;
        }
        .footer-link:hover {
            color: white;
        }

        @keyframes bounce {
            0%, 100% { transform: translateY(0); }
            50% { transform: translateY(-10px); }
        }
        @keyframes fadeInUp {
            from { opacity:0; transform:translateY(40px); }
            to { opacity:1; transform:translateY(0); }
        }

        /* ===== 响应式调整 ===== */
        @media (max-width: 768px) {
            .container {
                padding: 15px;
            }
            .card {
                margin-bottom: 20px;
            }
            .txt {
                padding: 20px 25px 25px;
            }
            .txt h3 {
                font-size: 1.3rem;
            }
            .txt p {
                font-size: 1rem;
            }
            .mixed-item .txt {
                padding: 20px 25px 25px;
            }
            .hero {
                background-attachment: scroll; /* 移动端取消固定背景 */
            }
            .play-button {
                padding: 14px 30px;
                font-size: 16px;
            }

            /* 移动端减少背景元素 */
            .bg-element:nth-child(3) {
                display: none;
            }

            /* 移动端简化背景图案 */
            body {
                background-image:
                        radial-gradient(circle at 15% 50%, rgba(0, 76, 112, 0.08) 0%, transparent 20%),
                        radial-gradient(circle at 85% 30%, rgba(42, 157, 143, 0.08) 0%, transparent 20%);
            }
        }

        @media (max-width: 480px) {
            .hero h1 {
                font-size: 2.2rem;
            }
            .hero p {
                font-size: 1rem;
            }
            .play-button {
                padding: 12px 25px;
                font-size: 15px;
            }

            /* 移动端进一步减少背景元素 */
            .bg-element:nth-child(2) {
                display: none;
            }
        }
    </style>
</head>

<body>
<!-- 顶部装饰花纹 -->
<div class="top-pattern"></div>

<!-- 背景装饰元素 -->
<div class="bg-elements">
    <div class="bg-element"></div>
    <div class="bg-element"></div>
    <div class="bg-element"></div>
</div>

<!-- 底部装饰花纹 -->
<div class="bottom-pattern"></div>

<!-- ===== Hero ===== -->
<div class="hero" id="hero">
    <div class="hero-content">
        <h1 id="heroTitle"></h1>
        <p id="heroSub"></p>
        <button class="play-button" id="playButton">🔊 播放语音介绍</button>
        <div class="audio-tip" id="audioTip">点击按钮播放语音</div>
    </div>
    <div class="scroll-tip">↓</div>
    <audio id="audio-element"></audio>
</div>

<!-- ===== 竖版卡片列表 ===== -->
<div class="container" id="list"></div>

<!-- ===== 页脚 ===== -->
<div class="footer">
    <div class="footer-links">
        <a href="#" class="footer-link">关于我们</a>
        <a href="#" class="footer-link">联系我们</a>
        <a href="#" class="footer-link">隐私政策</a>
    </div>
</div>

<script th:inline="javascript">
    /* 1. 后端注入（本地测试可写死） */
    window.CONFIG = /*[[${configJson}]]*/ {};

    window.CONFIG = JSON.parse(window.CONFIG);
</script>

<script>
    /* ===== 语音播放（同原逻辑） ===== */
    const audioEl  = document.getElementById('audio-element');
    const playBtn  = document.getElementById('playButton');
    const audioTip = document.getElementById('audioTip');
    let audioUrl   = null;
    let isLoaded   = false;

    function loadAudio(){
        fetch('http://192.168.10.3:8085/api/tts?id='+window.CONFIG.hero.id,{method:'POST'})
            .then(r=>r.blob())
            .then(blob=>{
                audioUrl = URL.createObjectURL(blob);
                audioEl.src = audioUrl;
                audioEl.oncanplaythrough=()=>{isLoaded=true;audioTip.textContent='音频加载完成';}
                audioEl.onerror=()=>{audioTip.textContent='音频加载失败';playBtn.textContent='❌ 加载失败';}
            })
            .catch(e=>{audioTip.textContent='语音合成失败';playBtn.textContent='❌ 加载失败';});
    }
    function togglePlay(){
        if(!isLoaded){audioTip.textContent='音频加载中…';return;}
        if(audioEl.paused){
            audioEl.play();
            playBtn.textContent='⏸️ 暂停播放';
            audioTip.textContent='播放中…';
        }else{
            audioEl.pause();
            playBtn.textContent='🔊 继续播放';
            audioTip.textContent='已暂停';
        }
        audioEl.onended=()=>{playBtn.textContent='🔊 重新播放';audioTip.textContent='播放完成';}
    }
    playBtn.addEventListener('click',togglePlay);
    document.addEventListener('keydown',e=>{if(e.code==='Space'){e.preventDefault();togglePlay()}});
    loadAudio();

    /* ===== 渲染页面 ===== */
    const h = window.CONFIG.hero;
    document.getElementById('heroTitle').textContent = h.title;
    document.getElementById('heroSub').textContent  = h.subtitle;
    document.getElementById('hero').style.setProperty('--bg','url('+h.bg+')');

    const box = document.getElementById('list');
    window.CONFIG.modules.forEach((m, i) => {
        const card = document.createElement('div');
        card.className = 'card';
        card.style.animationDelay = i * 0.15 + 's';

        if (m.type === 'mixed') {
            // 图文类型：遍历 list 数组，每个元素包含 img 和 txt
            let mixedHTML = '';

            if (m.list && m.list.length > 0) {
                m.list.forEach((item, index) => {
                    mixedHTML += `
                        <div class="mixed-item ${index > 0 ? 'mixed-item-margin' : ''}">
                            <img src="${item.img}" loading="lazy">
                            <div class="txt">
                                <p>${item.txt}</p>
                            </div>
                        </div>
                    `;
                });
            }

            card.innerHTML = mixedHTML;
        } else if (m.type === 'image' || m.type === 'video') {
            const isVideo = m.type === 'video';
            const media = m.list.map(u =>
                isVideo ? `<video src="${u}" muted controls playsinline></video>` : `<img src="${u}" loading="lazy">`
            ).join('');

            card.innerHTML = `
                <div class="swipe">${media}</div>
                <div class="swipe-indicator">${m.list.map((_, i) =>
                `<div class="swipe-dot ${i === 0 ? 'active' : ''}"></div>`
            ).join('')}</div>
                <div class="txt"><p>${m.desc || '左右滑动查看'}</p></div>`;

            const swipe = card.querySelector('.swipe');
            const dots = card.querySelectorAll('.swipe-dot');
            if (swipe && dots.length > 0) {
                swipe.addEventListener('scroll', () => {
                    const idx = Math.round(swipe.scrollLeft / swipe.clientWidth);
                    dots.forEach((d, i) => d.classList.toggle('active', i === idx));
                });
            }
        } else if (m.type === 'text') {
            // 文本类型
            card.innerHTML = `
                <div class="txt">
                    <p>${m.text}</p>
                </div>`;
        }

        box.appendChild(card);
    });
</script>
</body>
</html>